home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Installer SDK 1.2.3 / Upgrader 1.2.3 & Engines / Upgrader 1.2.3 / Plug-in Examples / Simple App Launcher Plug-in / Plug-in Sources / SimpleAppLauncher.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  17.3 KB  |  631 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        SimpleAppLauncher.c
  3. */
  4.  
  5. #include <Types.h>
  6. #include <Memory.h>
  7. #include <LowMem.h>
  8. #include <Quickdraw.h>
  9. #include <Files.h>
  10. #include <Resources.h>
  11. #include <TextUtils.h>
  12. #include <TextEdit.h>
  13. #include <MixedMode.h>
  14. #include <Events.h>
  15. #include <Processes.h>
  16. #include <Gestalt.h>
  17. #include <Printing.h>
  18. #include <ToolUtils.h>
  19. #include <assert.h>
  20.  
  21. #include "SimpleAppLauncher.h"
  22.  
  23. // PROTOTYPES
  24.  
  25. static Boolean HandleEventForPluginModule(EventRecord *inEvent);
  26. static void TerminatePluginModule(void);
  27. static ShellErr HandleMouseDownInUtilsPanel(EventRecord *inEvent, Boolean *wasHandled);
  28. static ShellErr HandleMouseDownInSALPanel(EventRecord *inEvent, Boolean *wasHandled);
  29. static Boolean HandleMouseDownInHelpPanel(EventRecord *inEvent);
  30. static Boolean QuitProcess(ProcessSerialNumber *inApplicationPSN);
  31. static OSErr SetupSALPanel( SInt16 inPrefRsrcID);
  32. static OSErr SetupHelpPanel(void);
  33. static Boolean ShouldDrawColor(void);
  34. static void SendQuitEventToApplication(void);
  35. static ShellErr SetUpAppleEventHandlers();
  36. static ShellErr RemoveAppleEventHandlers();
  37. pascal OSErr ChildDiedHandler(const AppleEvent *inAppleEvent, const AppleEvent */* outReply */, SInt32 /* inRefcon */ );
  38.  
  39. // GLOBALS
  40.  
  41. DialogPtr             gSALPanel                 = NULL;
  42. DialogPtr             gHelpPanel                 = NULL;
  43. Boolean             gHelpPanelOpen             = false;
  44. Boolean             gApplicationLaunched     = false;
  45. ProcessSerialNumber gApplicationPSN;
  46. AEEventHandlerUPP     gChildDiedHandlerUPP    = NULL;
  47. Boolean             gQuitApponExit             = true;                                            //Set this to true if you want the application to quit when leaving the plugin.
  48. SInt16                 gPrefID;
  49. Boolean                gIsLaunchCheckBoxShowing = false;
  50.  
  51. //--------------------------------------------------------------------------------
  52. //    InitializePluginModule
  53. //--------------------------------------------------------------------------------
  54.  
  55. void InitializePluginModule(void *inPSTable, SInt32 inRefCon, Boolean inEnterAtBeginning)
  56. {
  57. #pragma unused (inRefCon,inEnterAtBeginning)
  58.     ShellErr     err;
  59.     SInt16        refNum = -1;
  60.  
  61.     EnterPlugin();
  62.     SetupPlugin(inPSTable);
  63.  
  64.     // Register our event handler routine
  65.     err = PSRegisterHandler(kEventHandlerID, (UniversalProcPtr)HandleEventForPluginModule);
  66.  
  67.     if (err == noErr)
  68.     {
  69.         // Resister our termination handler routine
  70.         err = PSRegisterHandler(kTerminationHandlerID, (UniversalProcPtr)TerminatePluginModule);
  71.  
  72.         if (err == noErr)
  73.         {
  74.             //Register ChildDied event handler
  75.             err = SetUpAppleEventHandlers();
  76.  
  77.             if (err == noErr)
  78.             {
  79.                 err = PSSetupNewPanel(kSALPanelRsrcID, &gSALPanel);
  80.                 if (err == noErr)
  81.                 {
  82.                     err = SetupSALPanel( LoWord( inRefCon ) );
  83.                     if (err == noErr)
  84.                         PSShowPanel(gSALPanel);
  85.                 }
  86.             }
  87.         }
  88.     }
  89.     
  90.     if (err != noErr)
  91.     {
  92.         PSErrorAlert(err, true, "\p", "\p", "\p", "\p", kQuitButtonIndex, kContinueNotQuitBtnIndex);
  93.         PSQuitShell(kDontAllowUserToContinue);
  94.     }
  95.     
  96.     ExitPlugin();
  97. }
  98.  
  99. //--------------------------------------------------------------------------------
  100. //    TerminatePluginModule
  101. //--------------------------------------------------------------------------------
  102.  
  103. static void TerminatePluginModule()
  104. {
  105.     PanelItemType     itemType;
  106.     Handle            itemHandle;
  107.     Rect            itemRect;
  108.  
  109.     EnterPlugin();
  110.  
  111.     // Save launch checkbox state, if checkbox is showing
  112.     if( gIsLaunchCheckBoxShowing && PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr )
  113.     {
  114.         Boolean        savedCheckboxState = GetControlValue( (ControlHandle)itemHandle ) != 0;
  115.  
  116.         PSSetGlobalData( 'lacb', ( GlobalDataPtr ) &savedCheckboxState, sizeof(Boolean) );
  117.     }
  118.     
  119.  
  120.     if (gQuitApponExit)
  121.     {
  122.         if (gApplicationLaunched)
  123.             SendQuitEventToApplication();
  124.     }
  125.     
  126.     RemoveAppleEventHandlers();
  127.  
  128.     ExitPlugin();
  129. }
  130.  
  131. //--------------------------------------------------------------------------------
  132. //    HandleEventForPluginModule
  133. //--------------------------------------------------------------------------------
  134.  
  135. static Boolean HandleEventForPluginModule(EventRecord *inEvent)
  136. {
  137.     ShellErr     err            = noErr;
  138.     Boolean     wasHandled     = false;
  139.  
  140.     EnterPlugin();
  141.  
  142.     switch (inEvent->what)
  143.     {
  144.  
  145.         case mouseDown:
  146.             if (FrontWindow() == gSALPanel)
  147.                 err = HandleMouseDownInSALPanel(inEvent, &wasHandled);
  148.             else if (FrontWindow() == gHelpPanel)                        // check for Help panel
  149.                 wasHandled = PSHandleHelpWindowEvent(gHelpPanel, inEvent);
  150.             break;
  151.  
  152.         case osEvt:                                                        // Resume events only!
  153.             if (((UInt32)inEvent->message >> 24) == suspendResumeMessage)
  154.             {
  155.                 if ((inEvent->message & resumeFlag) != 0)
  156.                     (void) PSHandleHelpWindowEvent(gHelpPanel, inEvent);
  157.             }
  158.             break;
  159.  
  160.         case kHighLevelEvent:
  161.             AEProcessAppleEvent(inEvent);
  162.  
  163.             wasHandled = true;
  164.             break;
  165.  
  166.         default:
  167.             break;
  168.     }
  169.     
  170.     ExitPlugin();
  171.     
  172.     return(wasHandled);
  173. }
  174.  
  175. //--------------------------------------------------------------------------------
  176. //    HandleMouseDownInSALPanel
  177. //--------------------------------------------------------------------------------
  178.  
  179. static ShellErr HandleMouseDownInSALPanel(EventRecord *inEvent, Boolean *wasHandled)
  180. {
  181.     ShellErr         err                 = noErr;
  182.     SALPrefsHandle     prefsHandle;
  183.     SInt16             itemHit;
  184.     Boolean         launchedOK;
  185.     AEDesc             optionalParameters;
  186.     PanelItemType     itemType;
  187.     Handle            itemHandle;
  188.     Rect            itemRect;
  189.  
  190.     prefsHandle = (SALPrefsHandle) GetResource(kSALPrefsResType, gPrefID);    // Just get the first one
  191.  
  192.     *wasHandled = false;
  193.  
  194.     if (PSGetPanelItemHit(gSALPanel, inEvent, &itemHit))
  195.     {
  196.         switch (itemHit)
  197.         {
  198.  
  199.             case kContinueButton:
  200.                 if (prefsHandle != NULL && (**prefsHandle).format == 3 )
  201.                 {
  202.                     if( gIsLaunchCheckBoxShowing && PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr && GetControlValue( (ControlHandle)itemHandle ) == 0 )
  203.                     {
  204.                         PSGoToNextPlugin(kUseDefaultNextModuleName);
  205.                         *wasHandled = true;
  206.                         break;
  207.                     }                        
  208.                 
  209.                     if (gApplicationLaunched)
  210.                     {                                                // If application has been launched
  211.                         SetFrontProcess(&gApplicationPSN);
  212.                     }
  213.                     else
  214.                     {
  215.                         // Launch Application
  216.                         optionalParameters.descriptorType = 'NULL';
  217.                         optionalParameters.dataHandle = NULL;
  218.                         launchedOK = PSLaunchFile((**prefsHandle).applicationflrfID, (**prefsHandle).documentflrfID, &optionalParameters, true, &gApplicationPSN);
  219.                         if (launchedOK)
  220.                             gApplicationLaunched = true;
  221.                         
  222.                         *wasHandled = true;
  223.                     }
  224.                 }
  225.                 else
  226.                     err = kNoPrefsErr;
  227.                 break;
  228.  
  229.             case kLaunchCheckBox:
  230.                 if( PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr )
  231.                     SetControlValue( (ControlHandle)itemHandle, ! GetControlValue( (ControlHandle)itemHandle ) );
  232.                 break;
  233.                 
  234.             case kHelpButton:
  235.                 DisplayHelp();
  236.                 *wasHandled = true;
  237.                 break;
  238.  
  239.             default:
  240.                 break;
  241.         }
  242.     }
  243.     return(err);
  244. }
  245.  
  246.  
  247. //--------------------------------------------------------------------------------
  248. //    DisplayHelp
  249. //--------------------------------------------------------------------------------
  250.  
  251. void DisplayHelp()
  252. {
  253.     ShellErr err = noErr;
  254.  
  255.     if (gHelpPanelOpen)                                                    // Is it already open ?
  256.     {
  257.         err = PSShowPanel(gHelpPanel);
  258.     }
  259.     else
  260.     {
  261.         PSDisplayHelpWindow(gHelpPanel);
  262.         gHelpPanelOpen = true;
  263.     }
  264.     
  265.     if (err != noErr)
  266.     {
  267.         PSErrorAlert(err, true, "\p", "\p", "\p", "\p", kQuitButtonIndex, kContinueNotQuitBtnIndex);
  268.         PSQuitShell(kDontAllowUserToContinue);
  269.     }
  270. }
  271.  
  272.  
  273. //--------------------------------------------------------------------------------
  274. //    SetupSALPanel
  275. //
  276. //    Sets up the various user items in the panel to their correct type, specifiying
  277. //    the data found in the SAL preference resource which is read from the ClientData
  278. //    file.
  279. //    This routine should be called after PSSetupNewPanel() but before PSShowPanel() for
  280. //    the SAL panel.
  281. //
  282. //    Parameters
  283. //
  284. //    Returns
  285. //--------------------------------------------------------------------------------
  286.  
  287. static OSErr SetupSALPanel( SInt16 inPrefRsrcID )
  288. {
  289.     SALPrefsHandle prefsHandle;
  290.     SALPrefsPtr prefsPtr;
  291.     OSErr err = noErr;
  292.  
  293.     if( inPrefRsrcID == 0 ) {
  294.         SInt16** theIDHandle = (SInt16**) GetResource( kResIDResType, 128 );    // Get Resource ID for plugin preference
  295.         if (theIDHandle != NULL)
  296.             gPrefID = **theIDHandle;
  297.         else
  298.             gPrefID = 3500;
  299.     }
  300.     else
  301.         gPrefID = inPrefRsrcID;
  302.  
  303.     prefsHandle = (SALPrefsHandle) GetResource(kSALPrefsResType, gPrefID);    // Get Resource Preference
  304.  
  305.     if (prefsHandle != NULL)
  306.     {
  307.         if ((**prefsHandle).format == 3)
  308.         {
  309.             TEHandle text;
  310.             SInt16 fontNum, fontStyle, fontSize;
  311.             PanelItemType itemType;
  312.             Handle itemHandle;
  313.             Handle docHandle;
  314.             Rect itemRect;
  315.             PicHandle picHandle = NULL;
  316.  
  317.             HLock((Handle)prefsHandle);
  318.             prefsPtr = *prefsHandle;
  319.  
  320.             // Setup the panel title string.
  321.             err = PSGetPanelItem(gSALPanel, kTitleTextItem, &itemType, &itemHandle, &itemRect);
  322.             if (err == noErr)
  323.             {
  324.                 if (PSReadFontInfo(kFontInfoInShell, kUpgraderFonts, kLargeTextStyle, &fontNum, &fontStyle, &fontSize))
  325.                 {
  326.                     text = PSNewStyledStringItem(&itemRect, prefsPtr->SALSTRListRsrsID, 1, fontNum, fontStyle, fontSize);
  327.                     if (text != NULL)
  328.                         err = PSSetPanelItem(gSALPanel, kTitleTextItem, kStyledStringType, (Handle)text, &itemRect);
  329.                     else
  330.                         err = kCannotLoadNeededResourceErr;
  331.                 }
  332.             }
  333.             
  334.             if (err == noErr)
  335.             {
  336.                 // Setup the SAL panel main text.
  337.                 if (prefsPtr->mainTextReferenceID != 0)                // Ignore id 0 if the Client does not want any text
  338.                 {
  339.                     err = PSGetPanelItem(gSALPanel, kInstallStepsTextItem, &itemType, &itemHandle, &itemRect);
  340.                     if (err == noErr)
  341.                     {
  342.                         if ((prefsPtr->flags & kMainTextInFile) == kMainTextInFile)
  343.                         {
  344.                             docHandle = PSNewDocViewerItem(gSALPanel, &itemRect, kDocFileType, prefsPtr->mainTextReferenceID, 0);
  345.                             if (docHandle != NULL)
  346.                                 err = PSSetPanelItem(gSALPanel, kInstallStepsTextItem, kDocFileType, (Handle)docHandle, &itemRect);
  347.                             else
  348.                                 err = kCannotLoadNeededResourceErr;
  349.                         }
  350.                         else
  351.                         {
  352.                             text = PSNewStyledTextItem(&itemRect, prefsPtr->mainTextReferenceID);
  353.                             if (text != NULL)
  354.                                 err = PSSetPanelItem(gSALPanel, kInstallStepsTextItem, kStyledTextType, (Handle)text, &itemRect);
  355.                             else
  356.                                 err = kCannotLoadNeededResourceErr;
  357.                         }
  358.                     }
  359.                 }
  360.  
  361.                 // Setup the background PICT item
  362.                 if (prefsPtr->backgroundPICTResID != 0)                // Ignore id 0 if the Client does not want any background PICT
  363.                 {
  364.                     if (err == noErr)
  365.                     {
  366.  
  367.                         // Get color first
  368.                         if (ShouldDrawColor())
  369.                             picHandle = GetPicture(prefsPtr->backgroundPICTResID);
  370.                         else
  371.                             picHandle = GetPicture(prefsPtr->backgroundPICTResID + 1);
  372.  
  373.                         if (picHandle == NULL)
  374.                             picHandle = GetPicture(prefsPtr->backgroundPICTResID);
  375.  
  376.                         if (picHandle != NULL)
  377.                         {
  378.                             err = PSGetPanelItem(gSALPanel, kBackgroundPICTitem, &itemType, &itemHandle, &itemRect);
  379.                             if (err == noErr)
  380.                                 err = PSSetPanelItem(gSALPanel, kBackgroundPICTitem, kPICTType, (Handle)picHandle, &itemRect);
  381.                         }
  382.                         else
  383.                         {
  384.                             err = kCannotLoadNeededResourceErr;
  385.                         }
  386.                     }
  387.                 }
  388.                 
  389.                 if( PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr )
  390.                 {
  391.  
  392.                     // Hide/show the launch checkbox
  393.                     if ( prefsPtr->flags & kShowLaunchCheckbox )
  394.                     {
  395.                         Str255        checkBoxNameStr;
  396.                         Boolean        savedCheckboxState;
  397.                         SInt32        actualSize;
  398.                         
  399.                         gIsLaunchCheckBoxShowing = true;
  400.                         ShowControl( (ControlHandle)itemHandle );
  401.  
  402.                         // Set checkbox title
  403.                         GetIndString( checkBoxNameStr, prefsPtr->SALSTRListRsrsID, 3 );
  404.                         SetControlTitle( (ControlHandle)itemHandle, checkBoxNameStr );
  405.  
  406.                         // Set launch checkbox default state
  407.                         if ( prefsPtr->flags & kPrecheckLaunchCheckbox)
  408.                             SetControlValue( (ControlHandle)itemHandle, 1 );
  409.                         else
  410.                             SetControlValue( (ControlHandle)itemHandle, 0 );
  411.  
  412.                         // Override default checkbox state if we've saved the state using global data 
  413.                         if( PSGetGlobalData( 'lacb', ( GlobalDataPtr ) &savedCheckboxState, sizeof(Boolean), &actualSize ) == noErr )
  414.                         {
  415.                             if ( savedCheckboxState)
  416.                                 SetControlValue( (ControlHandle)itemHandle, 1 );
  417.                             else
  418.                                 SetControlValue( (ControlHandle)itemHandle, 0 );
  419.                         }    
  420.  
  421.                     }
  422.                     else
  423.                     {
  424.                         gIsLaunchCheckBoxShowing = false;
  425.                         HideControl( (ControlHandle)itemHandle );
  426.                     }
  427.                         
  428.  
  429.                 }
  430.                 
  431.                 // Find out if Application should be left open when exiting plugin
  432.                 if ((prefsPtr->flags & kKeepApplicationOpen) == kKeepApplicationOpen)
  433.                     gQuitApponExit = false;
  434.             }
  435.             HUnlock((Handle)prefsHandle);
  436.         }
  437.         else
  438.         {
  439.             err = kUnsupportedPrefsFormatErr;
  440.         }
  441.     }
  442.     else
  443.     {
  444.         err = kNoPrefsErr;
  445.     }
  446.  
  447.     PSSetPanelItemAction(gSALPanel, kContinueButton, kDefaultButtonMask);
  448.     PSSetPanelItemAction(gSALPanel, kGoBackButton, kGoBackButtonMask);
  449.  
  450.     if (err == noErr)
  451.         err = SetupHelpPanel();
  452.         
  453.     return(err);
  454. }
  455.  
  456. //--------------------------------------------------------------------------------
  457. //    SetupHelpPanel
  458. //
  459. //    Sets up the various user items in the panel to their correct type, specifiying
  460. //    the data found in the SAL preference resource which is read from the ClientData
  461. //    file.
  462. //    This routine should be called after PSSetupNewPanel() but before PSShowPanel() for
  463. //    the Help panel.
  464. //
  465. //    Parameters
  466. //
  467. //    Returns
  468. //--------------------------------------------------------------------------------
  469.  
  470. static OSErr SetupHelpPanel()
  471. {
  472.     SALPrefsHandle prefsHandle;
  473.     SALPrefsPtr prefsPtr;
  474.     OSErr err = noErr;
  475.  
  476.     prefsHandle = (SALPrefsHandle) GetResource(kSALPrefsResType, gPrefID);    // Just get the first one
  477.  
  478.     if (prefsHandle != NULL)
  479.     {
  480.         if ((**prefsHandle).format == 3)
  481.         {
  482.             Str255 helpPanelTitle;
  483.  
  484.             HLock((Handle)prefsHandle);
  485.             prefsPtr = *prefsHandle;
  486.  
  487.             if ((prefsPtr->flags & kHelpTextInFile) == kHelpTextInFile)
  488.             {
  489.                 GetIndString(helpPanelTitle, prefsPtr->SALSTRListRsrsID, 2);
  490.                 err = PSSetupHelpWindow(kReadFromSimpleTextFile, prefsPtr->helpTextReferenceID, prefsPtr->basePICTResID, helpPanelTitle, &gHelpPanel);
  491.             }
  492.             else
  493.             {
  494.                 GetIndString(helpPanelTitle, prefsPtr->SALSTRListRsrsID, 2);
  495.                 err = PSSetupHelpWindow(kReadFromResourceFile, prefsPtr->helpTextReferenceID, prefsPtr->basePICTResID, helpPanelTitle, &gHelpPanel);
  496.             }
  497.             HUnlock((Handle)prefsHandle);
  498.         }
  499.         else
  500.         {
  501.             err = kUnsupportedPrefsFormatErr;
  502.         }
  503.     }
  504.     else
  505.     {
  506.         err = kNoPrefsErr;
  507.     }
  508.     return(err);
  509. }
  510.  
  511.  
  512. //--------------------------------------------------------------------------------
  513. //    ShouldDrawColor
  514. //
  515. // IN: none
  516. // OUT: Boolean indicating true if we've got a color quickdraw
  517. // monitor with sufficient colors to display our color picts
  518. //
  519. //--------------------------------------------------------------------------------
  520.  
  521. static Boolean ShouldDrawColor(void)
  522. {
  523.     SInt32 info;
  524.     return Gestalt(gestaltQuickdrawVersion, &info) == noErr && info >= gestalt8BitQD && (*(*GetMainDevice())->gdPMap)->pixelSize >= 8;
  525. }
  526.  
  527.  
  528. //--------------------------------------------------------------------------------
  529. //    SendQuitEventToApplication
  530. //
  531. // Function that Quits gApplicationPSN
  532. //
  533. //--------------------------------------------------------------------------------
  534.  
  535. void SendQuitEventToApplication()
  536. {
  537.     OSErr         theErr             = noErr;
  538.     AppleEvent     theResultEvent;
  539.  
  540.  
  541.     // Create target desc.
  542.     AEDesc theTargetApp;
  543.     theErr = AECreateDesc(typeProcessSerialNumber, &gApplicationPSN, sizeof(gApplicationPSN), &theTargetApp);
  544.  
  545.     // Bring them to the front in case they put up a modal dialog on quit (i.e. Save dialog).
  546.     SetFrontProcess(&gApplicationPSN);
  547.  
  548.     // Create event
  549.     if (theErr == noErr)
  550.     {
  551.         theErr = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theTargetApp, 0, 0, &theResultEvent);
  552.         AEDisposeDesc(&theTargetApp);
  553.     }
  554.  
  555.     // Send it
  556.     if (theErr == noErr)
  557.     {
  558.         AppleEvent theReply;
  559.         theReply.descriptorType = 'NULL';
  560.         theReply.dataHandle = NULL;
  561.  
  562.         theErr = AESend(&theResultEvent, &theReply, kAENoReply, kAENormalPriority, 200, NULL, NULL);
  563.  
  564.         AEDisposeDesc(&theReply);
  565.         AEDisposeDesc(&theResultEvent);
  566.     }
  567. }
  568.  
  569.  
  570. //--------------------------------------------------------------------------------
  571. //    SetUpAppleEventHandlers
  572. //--------------------------------------------------------------------------------
  573.  
  574. ShellErr SetUpAppleEventHandlers()
  575. {
  576.     ShellErr     err         = noErr;
  577.     gChildDiedHandlerUPP     = NewAEEventHandlerProc(ChildDiedHandler);
  578.  
  579.     // Any application
  580.     err = AEInstallEventHandler(kCoreEventClass, kAEApplicationDied, gChildDiedHandlerUPP, kAEApplicationDied, false);
  581.     if (err != noErr)
  582.         err = kInternalErr;
  583.  
  584.     return(err);
  585. }
  586.  
  587.  
  588. //--------------------------------------------------------------------------------
  589. //    RemoveAppleEventHandlers
  590. //--------------------------------------------------------------------------------
  591.  
  592. ShellErr RemoveAppleEventHandlers()
  593. {
  594.     ShellErr     err = noErr;
  595.  
  596.     err = AERemoveEventHandler(kCoreEventClass, kAEApplicationDied, gChildDiedHandlerUPP, false);
  597.     if (err != noErr)
  598.         err = kInternalErr;
  599.     else
  600.         DisposeRoutineDescriptor(gChildDiedHandlerUPP);
  601.  
  602.     return(err);
  603. }
  604.  
  605.  
  606. //--------------------------------------------------------------------------------
  607. //    ChildDiedHandler
  608. //--------------------------------------------------------------------------------
  609.  
  610. pascal OSErr ChildDiedHandler(const AppleEvent *inAppleEvent, const AppleEvent */* outReply */, SInt32 /* inRefcon */ )
  611. {
  612.     SInt32                 theActualSize;
  613.     DescType             returnedType;
  614.     ProcessSerialNumber thelQuitApplicationPSN;
  615.  
  616.     EnterPlugin();
  617.  
  618.     AEGetParamPtr(inAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber, &returnedType, &thelQuitApplicationPSN, sizeof(gApplicationPSN), &theActualSize);
  619.     
  620.     // Check to make sure that the application that quit is the application that was launched
  621.     if ((thelQuitApplicationPSN.highLongOfPSN == gApplicationPSN.highLongOfPSN) && (thelQuitApplicationPSN.lowLongOfPSN == gApplicationPSN.lowLongOfPSN))
  622.     {
  623.         gApplicationLaunched = false;
  624.         PSGoToNextPlugin(kUseDefaultNextModuleName);
  625.     }
  626.     
  627.     ExitPlugin();
  628.  
  629.     return noErr;
  630. }
  631.